/*
Copyright 2008  Four Roads LLC conact@4-roads.com

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either 
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with this library.  If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Web;
using System.Web.UI;
using System.Collections;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using CommunityServer.Components;
using CommunityServer.Controls;
using System.ComponentModel;
using ResourceManager = FourRoads.Links.Controls.ResourceManager;

namespace FourRoads.Links.Controls
{
	/// <summary>
	/// Summary description for LinkPageControl.
	/// </summary>
	public class LinkPageControl : ResLinkBaseTemplatedWebControl
	{
		#region Child Controls
			private IText prefix;
			private IButton prevButton;
			private Repeater pageRepeater;
			private IButton nextButton;
			private IText truncateOf;
			private IButton totalButton;
		#endregion
	
		public LinkPageControl()
		{

		}

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad (e);
			DataBind();
		}
		
		public override void DataBind()
		{
			if(!Page.IsPostBack)
			{
				base.DataBind();
				BindData();
			}
		}

		protected override void AttachChildControls()
		{
			prefix = FindText( "Prefix" );
			prevButton = FindButton( "PrevButton" );
			pageRepeater = (Repeater)FindControl( "PageRepeater" );
			nextButton = FindButton( "NextButton" );
			truncateOf = FindText( "TruncateOf" );
			totalButton = FindButton( "TotalButton" );

			pageRepeater.ItemDataBound += new RepeaterItemEventHandler(pageRepeater_ItemDataBound);
			pageRepeater.ItemCommand += new RepeaterCommandEventHandler(pageRepeater_ItemCommand);
			prevButton.Click += new EventHandler(page_Click);
			nextButton.Click += new EventHandler(page_Click);
			totalButton.Click += new EventHandler(page_Click);
		}

		[DefaultValue( false )]
		public virtual bool VisibleOnOnePage
		{
			get
			{
				Object state = ViewState["VisibleOnOnePage"];
		
				if(state != null)
					return (bool)state;

				return false;
			}
			set { ViewState["VisibleOnOnePage"] = value; }
		}

		[DefaultValue( true )]
		public virtual bool TruncatePages
		{
			get
			{
				Object state = ViewState["TruncatePages"];

				if(state != null)
					return (bool)state;

				return true;
			}
			set { ViewState["TruncatePages"] = value; }
		}

		[DefaultValue( 5 )]
		public virtual int TruncateCount
		{
			get
			{
				Object state = ViewState["TruncateCount"];

				if(state != null)
					return (int)state;

				return 5;
			}
			set { ViewState["TruncateCount"] = value; }
		}

		[DefaultValue( 1 )]
		public virtual int CurrentPage
		{
			get
			{
				Object state = ViewState["CurrentPage"];
				if(state != null)
					return (int)state;
				return 1;
			}
			set
			{
				ViewState["CurrentPage"] = value;
				SelectedPage = value;
			}
		}

		[DefaultValue( 1 )]
		public virtual int TotalPages
		{
			get
			{
				Object state = ViewState["TotalPages"];
				if(state != null)
					return (int)state;
				return 1;
			}
			set { ViewState["TotalPages"] = value; }
		}

		[DefaultValue( 1 )]
		public virtual int SelectedPage
		{
			get
			{
				Object state = ViewState["SelectedPage"];
				if(state != null)
					return (int)state;
				return 1;
			}
			set { ViewState["SelectedPage"] = value; }
		}

		[DefaultValue( "" )]
		public virtual string QueryName
		{
			get
			{
				Object state = ViewState["QueryName"];
				if(state != null)
					return (string)state;
				return string.Empty;
			}
			set { ViewState["QueryName"] = value; }
		}

		[DefaultValue( "" )]
		public virtual string NavigateUrl
		{
			get
			{
				Object state = ViewState["NavigateUrl"];
				if(state != null)
					return (string)state;
				return string.Empty;
			}
			set { ViewState["NavigateUrl"] = value; }
		}

		[DefaultValue( "" )]
		protected virtual string BaseUrl
		{
			get
			{
				Object state = ViewState["BaseUrl"];
				if(state != null)
					return (string)state;
				return string.Empty;
			}
			set { ViewState["BaseUrl"] = value; }
		}

		[DefaultValue( "" )]
		public virtual string PrefixText
		{
			get
			{
				Object state = ViewState["PrefixText"];
				if(state != null)
					return (string)state;
				return string.Empty;
			}
			set { ViewState["PrefixText"] = value; }
		}

		[DefaultValue( false )]
		public virtual bool UseClickEvent
		{
			get
			{
				Object state = ViewState["UseClickEvent"];
				if(state != null)
					return (bool)state;
				return false;
			}
			set { ViewState["UseClickEvent"] = value; }
		}

		private void BindData()
		{
			// If we only have one page, we might not need to show this control
			if((TotalPages <= 1) && !VisibleOnOnePage)
				this.Visible = false;
			else
				this.Visible = true;

			// Configure the Url
			BaseUrl = NavigateUrl;
			if(BaseUrl.IndexOf("?") != -1)
			{
				bool hasPart = false;
				string queryString = BaseUrl.Substring( BaseUrl.IndexOf("?") + 1 );
				string[] parts = queryString.Split('&');
				for(int i = 0 ; i < parts.Length ; i++)
				{
					if(parts[i].StartsWith(QueryName))
					{
						parts[i] = QueryName + "={0}";
						hasPart = true;
					}
				}
				if(hasPart == true)
					BaseUrl = BaseUrl.Replace(queryString, string.Join("&", parts));
				else
					BaseUrl = BaseUrl.Replace(queryString, string.Join("&", parts) + "&" + QueryName + "={0}");
			}
			else
				BaseUrl = BaseUrl + "?" + QueryName + "={0}";

			// Variables
			int startPage = 1;
			int endPage = TotalPages;
			bool doTruncating = false;

			if((TruncatePages) && (TotalPages > TruncateCount))
			{
				doTruncating = true;

				// Find the start page
				if((CurrentPage - (TruncateCount / 2)) <= 1)
					startPage = 1;
				else
					startPage = CurrentPage - (TruncateCount / 2);

				// Find the end page
				if((startPage + TruncateCount) <= TotalPages)
					endPage = startPage + TruncateCount - 1;
				else
					startPage = TotalPages - TruncateCount + 1;
			}

			// Add the prefix
			if(prefix != null)
				prefix.Text = PrefixText;

			// Add the Prev link
			if(prevButton != null)
			{
				if(CurrentPage > 1)
				{
					prevButton.Text = "&lt;&lt;";
					prevButton.CommandArgument = (CurrentPage - 1).ToString();
					prevButton.Visible = true;
				}
				else
					prevButton.Visible = false;
			}

			// Loop through and add the pages
			ArrayList pages = new ArrayList();
			for(int i = startPage ; i <= endPage ; i++)
				pages.Add(i.ToString());
			pageRepeater.DataSource = pages;
			pageRepeater.DataBind();

			// Add the Next link
			if(nextButton != null)
			{
				if(CurrentPage < TotalPages)
				{
					nextButton.Text = "&gt;&gt;";
					nextButton.CommandArgument = (CurrentPage + 1).ToString();
					nextButton.Visible = true;
				}
				else
					nextButton.Visible = false;
			}

			// Add the "of x" text
			if(totalButton != null)
			{
				if(doTruncating)
				{
					totalButton.Text = TotalPages.ToString();
					totalButton.CommandArgument = TotalPages.ToString();
					totalButton.Visible = true;
					if(truncateOf != null)
						truncateOf.Visible = true;
				}
				else
				{
					totalButton.Visible = false;
					if(truncateOf != null)
						truncateOf.Visible = false;
				}
			}
		}

		private void pageRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
		{
			string page = e.Item.DataItem as string;

			switch(e.Item.ItemType)
			{
				case ListItemType.Item:
				case ListItemType.AlternatingItem:

					if(CurrentPage.ToString() != page)
					{
						LinkButton pageButton = (LinkButton)e.Item.FindControl( "PageButton" );
						if(pageButton != null)
						{
							pageButton.Text = page;
							pageButton.CommandArgument = page;
							pageButton.Click += new EventHandler(page_Click);
						}
					}
					else
					{
						e.Item.Controls.Clear();
						e.Item.Controls.Add( new LiteralControl( "<span class=\"currentPage\">" + page + "</span>" ) );
					}

					break;
			}
		}

		private void pageRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
		{
			int page = int.Parse((string)e.CommandArgument);

			if(UseClickEvent)
			{
				if(SelectedPage != page)
				{
					SelectedPage = page;
					OnPageChange(e);
				}
			}
			else
				Page.Response.Redirect( string.Format(BaseUrl, page), true );
		}

		private void page_Click(object sender, EventArgs e)
		{
			LinkButton button = (LinkButton)sender;
			int page = int.Parse(button.CommandArgument);

			if(UseClickEvent)
			{
				if(SelectedPage != page)
				{
					SelectedPage = page;
					OnPageChange(e);
				}
			}
			else
				Page.Response.Redirect( string.Format(BaseUrl, page), true );
		}

		public event EventHandler PageChanged;

		protected void OnPageChange(EventArgs e)
		{
			if(PageChanged != null)
				PageChanged(this, e);
		}
	}
}
